﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Eirene.CLI.Services;
using Eirene.Core.Model;

namespace Eirene.CLI
{
    /// <summary>
    /// Main application class.
    /// </summary>
    public class Main
    {
        #region Constructors

        public Main()
        {
            Console = new WindowsConsole();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets a list of items. 
        /// </summary>
        public ItemContainer Items { get; set; }

        /// <summary>
        /// Gets or set a welcome message for the application.
        /// </summary>
        public MessageService WelcomeMessage { get; set; }

        /// <summary>
        /// Console interface used for UI.
        /// </summary>
        public IWindowsConsole Console { get; set; }

        #endregion

        #region Public Methods

        public void AddNewItem()
        {
            bool validChoice;
            string userChoice;

            do
            {
                validChoice = true;

                // Get user's choice
                Console.WriteLine("\n\nMenu");
                Console.WriteLine("1 - Add a new item");
                Console.WriteLine("0 - Exit");

                userChoice = Console.ReadLine();
                int iUserChoice;

                if (int.TryParse(userChoice, out iUserChoice))
                {
                    switch (iUserChoice)
                    {
                        case 1:
                            // Invite the user to add a new item.
                            var newItem = new Item(); 
                            Console.WriteLine("\n\n\nAdd a new item:\n");

                            newItem.ItemName = EnterItemName();
                            newItem.Colour = EnterColour();
                            newItem.Price = EnterPrice();
                            newItem.Owners = EnterOwners(newItem.Owners);
                            newItem.Status = EnterStatus();

                            // Add to list.
                            Items.Add(newItem);
                            break;
                        case 0:
                            break;
                        default:
                            validChoice = false;
                            break;
                    }
                }
                else
                {
                    validChoice = false;
                }

                if (!validChoice)
                {
                    Console.WriteError(userChoice + " is not a valid choice. Please select from the menu.");
                }
            } while (userChoice != "0");
        }

        public void DisplayItemList(string listDesc)
        {
            if (Items != null)
            {
                Console.WriteLine(listDesc + " item list:");
                foreach (var item in Items)
                {
                    Console.WriteLine("\nItem " + Items.IndexOf(item));
                    Console.WriteLine("Name = " + item.ItemName);
                    Console.WriteLine("Colour = " + item.Colour);
                    Console.WriteLine(String.Format("Price = {0:C}", item.Price));
                    if (item.Owners != null)
                    {
                        var defaultOwner = string.Empty;
                        foreach (var owner in item.Owners)
                        {
                            if (owner.IsDefault)
                            {
                                defaultOwner = " - Default Owner.";
                            }
                            else
                            {
                                defaultOwner = string.Empty;
                            }

                            Console.WriteLine("Owner " + item.Owners.IndexOf(owner) + " = " + owner.FirstName + " " + owner.LastName + defaultOwner);
                        }
                    }
                    else
                    {
                        Console.WriteLine("A default owner has not been assigned to this item.");
                    }
                    Console.WriteLine("Status = " + item.Status.Name);
                }
            }
            else
            {
                throw new ApplicationException("The Hats property has not been set.");
            }
        }

        public string EnterColour()
        {
            string colour = null;

            while (String.IsNullOrWhiteSpace(colour))
            {
                Console.Write("Enter the colour: ");
                colour = Console.ReadLine();
            }

            return colour;
        }

        public string EnterItemName()
        {
            string itemName = null;

            while (String.IsNullOrWhiteSpace(itemName))
            {
                Console.Write("Enter a unique item name: ");
                itemName = Console.ReadLine();

                if (Items != null)
                {
                    if (Items.ItemNameIsNotUnique(itemName))
                    {
                        Console.WriteLine("There is already an item with this name!");
                        itemName = null;
                    }
                }
            }

            return itemName;
        }

        public decimal EnterPrice()
        {
            decimal price;
            string inputVal = string.Empty;

            while (!decimal.TryParse(inputVal, out price))
            {
                Console.Write("Enter the price (numbers only) $");
                inputVal = Console.ReadLine();
            }

            return price;
        }

        public List<Owner> EnterOwners(List<Owner> owners)
        {
            Console.WriteLine("Enter the owner(s) of the item (type 'done' when finished)");

            while (true)
            {
                var owner = new Owner { IsDefault = false };

                Console.Write("Enter the owner's first name: ");
                owner.FirstName = Console.ReadLine();

                if (owner.FirstName == "done" || string.IsNullOrWhiteSpace(owner.FirstName))
                {
                    break;
                }

                Console.Write("Enter the owner's last name: ");
                owner.LastName = Console.ReadLine();

                if (owner.LastName == "done" || string.IsNullOrWhiteSpace(owner.LastName))
                {
                    break;
                }


                string inputVal = string.Empty;


                while (String.IsNullOrWhiteSpace(inputVal.Trim()) && inputVal.ToUpper() != "Y" && inputVal.ToUpper() != "N")
                {
                    Console.Write("Default owner? (Y/N): ");
                    inputVal = Console.ReadLine();
                }

                owner.IsDefault = (inputVal.ToUpper() == "Y");

                if (owner.IsDefault && owners.Count > 0)
                {
                    // Check for existing default owner in owners list as there can be only one 
                    // default owner for an item.
                    Owner defaultOwner = owners.SingleOrDefault(i => i.IsDefault == true);
                    if (defaultOwner != null)
                    {
                        defaultOwner.IsDefault = false;
                    }
                }

                owners.Add(owner);
            }

            // Remove any duplicate owners before returning the list.
            return Items.DistinctOwnerList(owners);
        }

        public Status EnterStatus()
        {
            string status = null;

            while (String.IsNullOrWhiteSpace(status))
            {
                Console.Write("Enter the status: ");
                status = Console.ReadLine();
            }

            return new Status(status);
        }

        #endregion
    }
}
